﻿#region Copyright (c) 2012-11, Olaf Kober <amarok.projects@gmail.com>
//================================================================================
//	Permission is hereby granted, free of charge, to any person obtaining a copy
//	of this software and associated documentation files (the "Software"), to deal
//	in the Software without restriction, including without limitation the rights
//	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//	copies of the Software, and to permit persons to whom the Software is
//	furnished to do so, subject to the following conditions:
//
//	The above copyright notice and this permission notice shall be included in
//	all copies or substantial portions of the Software.
//
//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//	THE SOFTWARE.
//================================================================================
#endregion

#if TESTS

using System;
using NUnit.Framework;


namespace Amarok.Agents
{
	[TestFixture]
	public class Test_Message
	{
		[Serializable]
		public class MyMessage : Message
		{
		}


		// --- TESTS ---


		[Test]
		public void Test_Construction()
		{
			var instance = new MyMessage();

			Assert.That(instance.Id, Is.Not.EqualTo(Guid.Empty));
			Assert.That(instance.Label, Is.Null);
			Assert.That(instance.HasLabel, Is.False);
			Assert.That(instance.ToString(), Is.StringContaining("Amarok.Agents.Test_Message+MyMessage("));
			Assert.That(instance.ToString(), Is.StringContaining("Id: "));
			Assert.That(instance.ToString(), Is.StringContaining(", Label: <null>)"));
		}

		[Test]
		public void Test_Label()
		{
			var instance = new MyMessage();

			Assert.That(instance.Label, Is.Null);
			Assert.That(instance.HasLabel, Is.False);

			instance.Label = "COM1";

			Assert.That(instance.Label, Is.EqualTo("COM1"));
			Assert.That(instance.HasLabel, Is.True);

			Assert.Throws<InvalidOperationException>(() =>
				{
					instance.Label = "COM2";
				});

			Assert.That(instance.Label, Is.EqualTo("COM1"));
			Assert.That(instance.HasLabel, Is.True);
		}

		[Test]
		public void Test_Label_SetNull()
		{
			var instance = new MyMessage();

			Assert.Throws<ArgumentNullException>(() =>
				{
					instance.Label = null;
				});

			instance.Label = "COM1";

			Assert.Throws<ArgumentNullException>(() =>
				{
					instance.Label = null;
				});
		}

		[Test]
		public void Test_ResetLabel()
		{
			var instance = new MyMessage();

			Assert.That(instance.Label, Is.Null);
			Assert.That(instance.HasLabel, Is.False);

			instance.ResetLabel();

			Assert.That(instance.Label, Is.Null);
			Assert.That(instance.HasLabel, Is.False);

			instance.Label = "COM1";

			Assert.That(instance.Label, Is.EqualTo("COM1"));
			Assert.That(instance.HasLabel, Is.True);

			instance.ResetLabel();

			Assert.That(instance.Label, Is.Null);
			Assert.That(instance.HasLabel, Is.False);

			instance.Label = "COM2";

			Assert.That(instance.Label, Is.EqualTo("COM2"));
			Assert.That(instance.HasLabel, Is.True);
		}

		[Test]
		public void Test_Serialization_BinaryFormatter_WithoutLabel()
		{
			var instance1 = new MyMessage();
			var instance2 = TestHelper.TestBinaryFormatterRoundtrip(instance1);

			Assert.That(instance2, Is.Not.SameAs(instance1));
			Assert.That(instance2.Id, Is.EqualTo(instance1.Id));
			Assert.That(instance2.Label, Is.Null);
			Assert.That(instance2.HasLabel, Is.False);
		}

		[Test]
		public void Test_Serialization_BinaryFormatter_WithLabel()
		{
			var instance1 = new MyMessage();
			instance1.Label = "COM1";
			var instance2 = TestHelper.TestBinaryFormatterRoundtrip(instance1);

			Assert.That(instance2, Is.Not.SameAs(instance1));
			Assert.That(instance2.Id, Is.EqualTo(instance1.Id));
			Assert.That(instance2.Label, Is.EqualTo("COM1"));
			Assert.That(instance2.HasLabel, Is.True);
		}

		[Test]
		public void Test_Serialization_DataContract_WithoutLabel()
		{
			var instance1 = new MyMessage();
			var instance2 = TestHelper.TestDataContractRoundtrip(instance1);

			Assert.That(instance2, Is.Not.SameAs(instance1));
			Assert.That(instance2.Id, Is.EqualTo(instance1.Id));
			Assert.That(instance2.Label, Is.Null);
			Assert.That(instance2.HasLabel, Is.False);
		}

		[Test]
		public void Test_Serialization_DataContract_WithLabel()
		{
			var instance1 = new MyMessage();
			instance1.Label = "COM1";
			var instance2 = TestHelper.TestDataContractRoundtrip(instance1);

			Assert.That(instance2, Is.Not.SameAs(instance1));
			Assert.That(instance2.Id, Is.EqualTo(instance1.Id));
			Assert.That(instance2.Label, Is.EqualTo("COM1"));
			Assert.That(instance2.HasLabel, Is.True);
		}

		[Test]
		public void Test_GetHashCode()
		{
			Object a = new MyMessage();
			Object b = new MyMessage();
			Object c = a;

			Assert.AreEqual(true, a.GetHashCode() == a.GetHashCode());
			Assert.AreEqual(true, b.GetHashCode() == b.GetHashCode());
			Assert.AreEqual(true, c.GetHashCode() == c.GetHashCode());

			Assert.AreEqual(true, a.GetHashCode() == c.GetHashCode());
		}

		[Test]
		public void Test_Equals_Object()
		{
			Object a = new MyMessage();
			Object b = new MyMessage();
			Object c = a;
			Object d = -123;

			// x.Equals(x) == true
			Assert.AreEqual(true, a.Equals(a));
			Assert.AreEqual(true, b.Equals(b));
			Assert.AreEqual(true, c.Equals(c));
			Assert.AreEqual(true, d.Equals(d));

			// x.Equals(null) == false
			Assert.AreEqual(false, a.Equals((Object)null));
			Assert.AreEqual(false, b.Equals((Object)null));
			Assert.AreEqual(false, c.Equals((Object)null));
			Assert.AreEqual(false, d.Equals((Object)null));

			// x.Equals(y) == y.Equals(x)
			Assert.AreEqual(false, a.Equals(b));
			Assert.AreEqual(a.Equals(b), b.Equals(a));

			Assert.AreEqual(true, a.Equals(c));
			Assert.AreEqual(a.Equals(c), c.Equals(a));

			Assert.AreEqual(false, a.Equals(d));
			Assert.AreEqual(a.Equals(d), d.Equals(a));
		}

		[Test]
		public void Test_Equals_IEquatable()
		{
			MyMessage a = new MyMessage();
			MyMessage b = new MyMessage();
			MyMessage c = a;

			// x.Equals(x) == true
			Assert.AreEqual(true, a.Equals(a));
			Assert.AreEqual(true, b.Equals(b));
			Assert.AreEqual(true, c.Equals(c));

			// x.Equals(null) == false
			Assert.AreEqual(false, a.Equals((MyMessage)null));
			Assert.AreEqual(false, b.Equals((MyMessage)null));
			Assert.AreEqual(false, c.Equals((MyMessage)null));

			// x.Equals(y) == y.Equals(x)
			Assert.AreEqual(false, a.Equals(b));
			Assert.AreEqual(a.Equals(b), b.Equals(a));

			Assert.AreEqual(true, a.Equals(c));
			Assert.AreEqual(a.Equals(c), c.Equals(a));
		}

	}
}

#endif
